home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / pao / etc / cdir / src / sdump.c < prev    next >
Text File  |  1994-06-01  |  14KB  |  455 lines

  1. /* << MSC V5.1 >> [FM-TOWNS] ************************************************
  2. *
  3. *    カレントドライブのセクタダンププログラム(MS-DOS汎用)
  4. *    ----------------------------------------------------------------------
  5. *    All Rights Reserved, Copyright (C) Y.Hirata 1993.
  6. *    Programmed by Y.Hirata ( NIFTY-ID: NAB03321  パオパオ )
  7. *
  8. *    NOTE: TAB=4
  9. ****************************************************************************/
  10.  
  11. #include <stdio.h>            /*  printf,putchar    */
  12. #include <stdlib.h>            /*  exit        */
  13. #include <string.h>            /*  str*        */
  14. #include <jctype.h>            /*  iskanji*    */
  15. #include <direct.h>            /*  getcwd        */
  16. #include <conio.h>            /*  getch        */
  17.  
  18. #include "lib\define.h"        /*  定数宣言    */
  19. #include "lib\typedef.h"    /*  型宣言        */
  20. #include "lib\mem.h"        /*  _peek        */
  21. #include "lib\dirlib.h"        /*  <dos.h>,_aread    */
  22. #include "lib\doscall.h"    /*  <dos.h>,_getDPB    */
  23. #include "lib\crt.h"        /*  ANK,・・・        */
  24.  
  25. #define isdisp(c)  ((0x20 <= c && c < 0x7F) || (0xA0 <= c && c <= 0xDF))
  26.  
  27. _DPB    _dpb ;                                    /*  DPB情報                */
  28. int        FATbit ;                                /*  FATビットサイズ            */
  29.  
  30. unsigned    _cdrv ;                                /*  カレントドライブ            */
  31. char        *_cdir ;                            /*  カレントディレクトリ            */
  32. char        _abspath[128] ;                        /*  物理パス名            */
  33. BYTE        *_sctbuf ;                            /*  セクタ領域                */
  34. DWORD        _fsector ;                            /*  開始セクタ番号            */
  35. DWORD        _nsector ;                            /*  読み取りセクタ数        */
  36.  
  37. #define    LINEpPAGE            24                    /*  1画面の行数            */
  38. int            _linecnt ;                            /*  表示行数            */
  39.  
  40. struct {
  41.     unsigned    critical:1 ;    /*  致命的エラー発生フラグ    */
  42.     unsigned    fat:1 ;            /*  FAT読み込み済フラグ    */
  43.     unsigned    sct32:1 ;        /*  32bitサポートフラグ        */
  44.     unsigned    page:1 ;        /*  ページ制御            */
  45. } _flg ;                                        /*  処理フラグ            */
  46.  
  47. void putcrlf( void )
  48. /*===========================================================================
  49. *    改行表示
  50. ===========================================================================*/
  51. {
  52.     putchar( '\n' ) ;
  53.     if ( !_flg.page ) return ;
  54.     if ( ++_linecnt > LINEpPAGE-2 ) {
  55.         printf( "--- more ---" ) ;
  56.         getch() ;
  57.         putchar( '\n' ) ;
  58.         _linecnt=0 ;
  59.     }
  60. }
  61.  
  62. void getDPB( void )
  63. /*===========================================================================
  64. *    DPB情報取得
  65. ===========================================================================*/
  66. {
  67.     WORD    attr ;
  68.  
  69.     _getDPB( _cdrv,&_dpb ) ;
  70.     if ( _dpb.maxclst < 0x0FF7 ) {
  71.         FATbit  = 12 ;                            /*  12bit FAT        */
  72.     } else {
  73.         FATbit  = 16 ;                            /*  16bit FAT        */
  74.     }
  75.     if ( _osmajor >= 10 ) {                        /*  OS/2互換BOX        */
  76.         _flg.sct32 = 1 ;
  77.         return ;
  78.     }
  79.     attr = (WORD)_peek( _dpb.dseg,_dpb.doff+4 ) ;
  80.     _flg.sct32 = ( attr & 0x0002 ) ? 1 : 0 ;    /*  32bitセクタサポート?    */
  81. }
  82.  
  83. int absRead( WORD nsct,DWORD sctno,void *buf )
  84. /*===========================================================================
  85. *    物理読み込み
  86. *    < IN  >    : nsct    読み込みセクタ数
  87. *            : sctno    読み込み開始セクタ番号
  88. *            : buf    データ格納先アドレス
  89. *    < OUT >    : buf    読み込んだデータ
  90. *    < RET >    : 下位バイトにエラーコードを返す. (上位バイト=00h:正常終了, =01h:エラー発生)
  91. *                =00h    書き込み禁止である
  92. *                =01h    ユニットが存在しない
  93. *                =02h    ドライブの準備ができていない
  94. *                =03h    存在しないコマンドである
  95. *                =04h    データのCRCエラー
  96. *                =05h    バッドドライブリクエストストラクチャの長さ
  97. *                =06h    シークエラー
  98. *                =07h    存在しないメディアタイプである
  99. *                =08h    セクタが存在しない
  100. *                =09h    プリンタの用紙切れ
  101. *                =0Ah    書き込み不良
  102. *                =0Bh    読み込み不良
  103. *                =0Ch    一般的なディスク不良
  104. *                =0Fh    不正なメディア交換があった
  105. ===========================================================================*/
  106. {
  107.     struct {
  108.         DWORD    sctno ;                            /*  32bitセクタ番号        */
  109.         WORD    nsct ;                            /*  R/Wセクタ数            */
  110.         WORD    off ;                            /*  バッファオフセット            */
  111.         WORD    seg ;                            /*  バッファセグメント            */
  112.     } packet ;
  113.  
  114.     if ( _flg.sct32 ) {                            /*  32bitセクタサポート        */
  115.         packet.sctno = sctno ;
  116.         packet.nsct  = nsct ;
  117.         packet.off   = _off( buf ) ;
  118.         packet.seg   = _seg( buf ) ;
  119.         return _aread( _cdrv-1,-1,-1,&packet ) ;
  120.     }
  121.     return _aread( _cdrv-1,nsct,(WORD)sctno,buf ) ;
  122. }
  123.  
  124. void dispTitle( DWORD fsector )
  125. /*===========================================================================
  126. *    セクタダンプのタイトル表示
  127. *    < IN  >    : fsector    開始セクタ番号
  128. ===========================================================================*/
  129. {
  130.     putcrlf() ;
  131.     printf( "< セクタ番号 %lXh >",fsector ) ;
  132.     putcrlf() ;
  133.     printf( "---- + -- -- -- -- -- -- -- -- . " ) ;
  134.     printf( "-- -- -- -- -- -- -- -- + -------- -------- " ) ;
  135.     putcrlf() ;
  136. }
  137.  
  138. int dispKanji( int kanji1,int kanji2 )
  139. /*===========================================================================
  140. *    漢字表示(漢字1バイト目確定, 2バイト目非確定時の処理)
  141. *    < IN  >    : kanji1    漢字1バイト目
  142. *            : kanji2    漢字2バイト目
  143. *    < RET >    : 漢字表示有無
  144. *                =0    漢字表示(2バイト表示)
  145. *                =1    非漢字表示(1バイト表示)
  146. ===========================================================================*/
  147. {
  148.     if ( iskanji2( kanji2 ) ) {                    /*  漢字表示            */
  149.         putchar( kanji1 ) ;
  150.         putchar( kanji2 ) ;
  151.         return 0 ;
  152.     } else {                                    /*  制御文字表示        */
  153.         putchar( '.' ) ;
  154.         return 1 ;
  155.     }
  156. }
  157.  
  158. void dispAscii( WORD off,int *prech,int *kanji )
  159. /*===========================================================================
  160. *    ASCII/S-JIS表示
  161. *    < IN  >    : off    オフセット
  162. *            : prech    ひとつ前の値
  163. *            : kanji    漢字チェックフラグ
  164. *    < OUT >    : prech    最後の値(漢字1バイト目)
  165. *            : kanji    漢字チェックフラグ
  166. ===========================================================================*/
  167. {
  168.     register WORD    cnt ;
  169.  
  170.     if ( *kanji != ANK ) {                        /*  先頭が漢字2バイト目    */
  171.         putchar( ' ' ) ;
  172.         *kanji = ANK ;
  173.     } else {
  174.         *kanji = iskanji( _sctbuf[off] ) ? KANJI1 : ANK ;
  175.         if ( *kanji == ANK ) {                    /*  漢字1バイト目以外        */
  176.             if ( isdisp( _sctbuf[off] ) )        /*  表示可能文字        */
  177.                 putchar( _sctbuf[off] ) ;
  178.             else                                /*  制御文字等            */
  179.                 putchar( '.' ) ;
  180.         } else                                    /*  漢字1バイト目=保留    */
  181.             *prech = _sctbuf[off] ;
  182.     }
  183.     off++ ;
  184.     for ( cnt=1; cnt<16; cnt++, off++ ) {        /*  2文字目以降表示        */
  185.         if ( cnt == 8 && *kanji == ANK ) putchar( ' ' ) ;
  186.         if ( off < _dpb.bps ) {                    /*  データ読取範囲内        */
  187.             if ( *kanji != ANK ) {                /*  漢字2バイト目?        */
  188.                 if ( dispKanji( *prech,_sctbuf[off] ) ) {
  189.                     *kanji = iskanji( _sctbuf[off] ) ? KANJI1 : ANK ;
  190.                 } else                            /*  漢字表示済            */
  191.                     *kanji = KANJI2 ;
  192.                 if ( cnt == 8 ) putchar( ' ' ) ;
  193.             } else {                            /*  漢字1バイト目/ANK        */
  194.                 *kanji = iskanji( _sctbuf[off] ) ? KANJI1 : ANK ;
  195.             }
  196.             if ( *kanji == ANK ) {                /*  ANK(漢字以外)        */
  197.                 if ( isdisp( _sctbuf[off] ) )
  198.                     putchar( _sctbuf[off] ) ;
  199.                 else
  200.                     putchar( '.' ) ;
  201.             } else                                /*  漢字1バイト目=保留    */
  202.                 *prech = _sctbuf[off] ;
  203.             if ( *kanji == KANJI2 ) *kanji = ANK ;
  204.         } else                                    /*  データ読取範囲外        */
  205.             putchar( '.' ) ;
  206.     }
  207. }
  208.  
  209. int dispSector( DWORD sector )
  210. /*===========================================================================
  211. *    セクタ内容表示
  212. *    < IN  >    : sector    セクタ番号
  213. *    < RET >    : 最後の表示有無
  214. *                =0    ANK(表示済)
  215. *                =1    未表示(最後の1バイト表示待ち)
  216. ===========================================================================*/
  217. {
  218.     register WORD    cnt, off=0 ;
  219.     static int    prech=0, kanji=ANK ;
  220.  
  221.     if ( kanji != ANK ) {                        /*  前回未表示分あり    */
  222.         if ( dispKanji( prech,_sctbuf[0] ) ) kanji = ANK ;
  223.     }
  224.     dispTitle( sector ) ;                        /*  タイトル表示            */
  225.     for ( off=0; off<_dpb.bps; off+=16 ) {
  226.         if ( off ) {
  227.             if ( kanji != ANK ) {                /*  前行未表示分あり    */
  228.                 if ( dispKanji( prech,_sctbuf[off] ) ) kanji = ANK ;
  229.             }
  230.             putcrlf() ;                            /*  改行                */
  231.         }
  232.         printf( "%04X |",off ) ;                /*  オフセット表示            */
  233.         for ( cnt=0; cnt<16; cnt++, off++ ) {    /*  dump                */
  234.             if ( cnt == 8 ) printf( " -" ) ;
  235.             if ( off < _dpb.bps )                /*  データ読取範囲内        */
  236.                 printf( " %02X",_sctbuf[off] ) ;
  237.             else                                /*  データ読取範囲外        */
  238.                 printf( " .." ) ;
  239.         }
  240.         off -= 16 ;
  241.         printf( " | " ) ;
  242.         dispAscii( off,&prech,&kanji ) ;        /*  ASCII/S-JIS表示        */
  243.     }
  244.     return kanji==ANK ? 0 : 1 ;
  245. }
  246.  
  247. int dump( void )
  248. /*===========================================================================
  249. *    セクタダンプ
  250. *    < RET >    : エラコードを返す.
  251. *                =0    正常終了
  252. *                =1    セクタ読み込み失敗
  253. ===========================================================================*/
  254. {
  255.     DWORD    cnt ;
  256.     int        ret ;
  257.  
  258.     for ( cnt=0L; cnt<_nsector; cnt++ ) {
  259.         ret = absRead( 1,_fsector+cnt,_sctbuf ) ;
  260.         if ( ret ) {
  261.             printf( "\aセクタ読み込み失敗 _aread error : %02Xh",_lo(ret) ) ;
  262.             printf( ", セクタ番号 %lXh",_fsector+cnt ) ;
  263.             putcrlf() ;
  264.             return 1 ;
  265.         }
  266.         ret = dispSector( _fsector+cnt ) ;        /*  セクタ内容表示            */
  267.     }
  268.     if ( ret ) putchar( '.' ) ;
  269.     putcrlf() ;
  270.     return 0 ;
  271. }
  272.  
  273. int abschk( void )
  274. /*===========================================================================
  275. *    物理アクセスのチェック
  276. ===========================================================================*/
  277. {
  278.     if ( getabspath( _cdir,_abspath ) ) {        /*  物理パス名取得        */
  279.         _flg.critical = 1 ;
  280.         printf( "\a ドライブの指定が違います." ) ;
  281.         putcrlf() ;
  282.         return 1 ;
  283.     }
  284.     if ( isnetdrv( _cdrv ) ) {                    /*  リモート                */
  285.         putcrlf() ;
  286.         printf( "\a %c: はリモートドライブ",_cdrv+'@' ) ;
  287.         printf( "(DOSによる物理アクセス不可)のため扱えません." ) ;
  288.         putcrlf() ;
  289.         return 1 ;
  290.     }
  291.     if ( isjoindrv( _cdrv ) || stricmp( _cdir,_abspath ) ) {
  292.         putcrlf() ;
  293.         printf( "\a このドライブは再割当されています." ) ;
  294.         putcrlf() ;
  295.         printf( "   物理パス名は %s",_abspath ) ;
  296.         putcrlf() ;
  297.     }
  298.     return 0 ;
  299. }
  300.  
  301. int init( void )
  302. /*===========================================================================
  303. *    初期処理
  304. *    < RET >    : エラコードを返す.
  305. *                =0    正常終了
  306. *                =1    メモリ不足
  307. *                =2    物理アクセス不可
  308. ===========================================================================*/
  309. {
  310.     _flg.critical = 0 ;
  311.     resetdisk() ;                                /*  リセットディスク            */
  312.     _dos_getdrive( &_cdrv ) ;                    /*  カレントドライブ            */
  313.     _cdir = getcwd( NULL,_MAX_DIR ) ;            /*  カレントディレクトリ取得        */
  314.     if ( abschk() ) return 2 ;                    /*  物理アクセスチェック        */
  315.     getDPB() ;                                    /*  DPB情報取得            */
  316.     if ( (_sctbuf = (BYTE *)malloc( _dpb.bps )) == NULL ) {
  317.         printf( "\a作業領域(%dbyte)が確保できませんでした.",_dpb.bps ) ;
  318.         putcrlf() ;
  319.         return 1 ;
  320.     }
  321.     return 0 ;
  322. }
  323.  
  324. void dispDpb( void )
  325. /*===========================================================================
  326. *    ディスク情報表示
  327. ===========================================================================*/
  328. {
  329.     putcrlf() ;
  330.     printf( "< %d bit FAT >",FATbit ) ;
  331.     if ( _flg.sct32 ) printf( " ( 32bitセクタ番号サポート )" ) ;
  332.     putcrlf() ;
  333.     printf( "bytes/sector .................. %u",_dpb.bps ) ;
  334.     putcrlf() ;
  335.     printf( "sectors/cluster ............... %u",_dpb.spc+1 ) ;
  336.     putcrlf() ;
  337.     printf( "reserved sectors .............. %u",_dpb.res ) ;
  338.     putcrlf() ;
  339.     printf( "sectors/FAT ................... %u",_dpb.spf ) ;
  340.     putcrlf() ;
  341.     printf( "first data sector ............. %04Xh",_dpb.fds ) ;
  342.     putcrlf() ;
  343.     printf( "first sector of root directry . %04Xh",_dpb.fsr ) ;
  344.     putcrlf() ;
  345. }
  346.  
  347. void usage( void )
  348. /*===========================================================================
  349. *    使用方法表示
  350. ===========================================================================*/
  351. {
  352.     printf( "セクタダンプ (C) パオパオ 1993.\n\n" ) ;
  353.     printf( "Usage: sdump 開始セクタ番号 [セクタ数] [-p]\n" ) ;
  354.     printf( "       -p   1画面毎表示\n" ) ;
  355.     printf( "( 16進数値は, ********H です. )\n" ) ;
  356.     exit( 1 ) ;
  357. }
  358.  
  359. void swchk( char *str )
  360. /*===========================================================================
  361. *    オプションスイッチ評価
  362. ===========================================================================*/
  363. {
  364.     register int    cnt ;
  365.  
  366.     for ( cnt=0; cnt<strlen(str); cnt++ ) {
  367.         if ( str[cnt] == '-' || str[cnt] == '/' ) continue ;
  368.         switch ( str[cnt] ) {
  369.         case 'p'    :
  370.         case 'P'    :
  371.             _flg.page = TRUE ;        break ;
  372.         default        :
  373.             usage() ;
  374.         }
  375.     }
  376. }
  377.  
  378. int atoc( BYTE ch,int radix )
  379. /*===========================================================================
  380. *    文字→数字
  381. ===========================================================================*/
  382. {
  383.     if ( ch >= '0' && ch <= '9' ) return ( ch - '0' ) ;
  384.     if ( radix == 16 ) {
  385.         if ( ch >= 'a' && ch <= 'f' ) return ( ch - 'a' + 10 ) ;
  386.         if ( ch >= 'A' && ch <= 'F' ) return ( ch - 'A' + 10 ) ;
  387.     }
  388.     printf( "\a数値の指定に誤りがあります.\n" ) ;
  389.     exit( 1 ) ;
  390. }
  391.  
  392. DWORD atohl( char *str )
  393. /*===========================================================================
  394. *    文字列→数字(double word)
  395. ===========================================================================*/
  396. {
  397.     register int    cnt ;
  398.     int        len=strlen( str ) ;
  399.     BYTE    ch ;
  400.     DWORD    val=0L ;
  401.  
  402.     ch = str[len-1] ;
  403.     if ( ch == 'h' || ch == 'H' ) {                /*  16進数                */
  404.         for ( cnt=0; cnt<len-1; cnt++ ) {
  405.             val <<= 4 ;
  406.             val += (DWORD)atoc( str[cnt],16 ) ;
  407.         }
  408.     } else {                                    /*  10進数                */
  409.         for ( cnt=0; cnt<len; cnt++ ) {
  410.             val *= 10L ;
  411.             val += (DWORD)atoc( str[cnt],10 ) ;
  412.         }
  413.     }
  414.     return val ;
  415. }
  416.  
  417. int main( int ac,char *av[] )
  418. /*===========================================================================
  419. *    メイン
  420. ===========================================================================*/
  421. {
  422.     int        ret, cnt ;
  423.  
  424.     if ( ac < 2 ) usage() ;                        /*  使用方法表示        */
  425.     _flg.page = 0 ;
  426.     _linecnt  = 0 ;
  427.     _nsector  = 1L ;
  428.     for ( ret=0, cnt=1; cnt<ac; cnt++ ) {
  429.         if ( *av[cnt] == '-' || *av[cnt] == '/' )
  430.             swchk( av[cnt]+1 ) ;                /*  引数チェック            */
  431.         else {
  432.             switch ( ret ) {
  433.             case 0    :
  434.                 _fsector = atohl( av[cnt] ) ;    /*  開始セクタ番号            */
  435.                 ret++ ;
  436.                 break ;
  437.             case 1    :
  438.                 _nsector = atohl( av[cnt] ) ;    /*  読み取りセクタ数        */
  439.                 ret++ ;
  440.                 break ;
  441.             default    :
  442.                 usage() ;                        /*  使用方法表示        */
  443.             }
  444.         }
  445.     }
  446.     ret = init() ;                                /*  初期処理            */
  447.     if ( ret != 2 ) dispDpb() ;                    /*  ディスク情報表示        */
  448.     if ( !ret ) dump() ;                        /*  セクタダンプ            */
  449.     if ( _sctbuf != NULL ) free( _sctbuf ) ;    /*  データクリア                */
  450.     resetdisk() ;                                /*  リセットディスク            */
  451.  
  452.     return 0 ;
  453. }
  454.  
  455.